package handler

import (
	"context"

	log "github.com/micro/go-micro/v2/logger"

	"gitee.com/waagik/demo/common"
	"gitee.com/waagik/demo/domain/model"
	"gitee.com/waagik/demo/domain/service"
	"gitee.com/waagik/demo/proto/demo"
)

type Demo struct{}

// Call is a single request handler called via client.Call or the generated client code
func (h *Demo) Call(ctx context.Context, req *demo.Request, rsp *demo.Response) error {
	log.Info("Received Demo.Call request")
	rsp.Msg = "Hello " + req.Name
	return nil
}

// Stream is a server side stream handler called via client.Stream or the generated client code
func (h *Demo) Stream(ctx context.Context, req *demo.StreamingRequest, stream demo.Demo_StreamStream) error {
	log.Infof("Received Demo.Stream request with count: %d", req.Count)

	for i := 0; i < int(req.Count); i++ {
		log.Infof("Responding: %d", i)
		if err := stream.Send(&demo.StreamingResponse{
			Count: int64(i),
		}); err != nil {
			return err
		}
	}

	return nil
}

// PingPong is a bidirectional stream handler called via client.Stream or the generated client code
func (h *Demo) PingPong(ctx context.Context, stream demo.Demo_PingPongStream) error {
	for {
		req, err := stream.Recv()
		if err != nil {
			return err
		}
		log.Infof("Got ping %v", req.Stroke)
		if err := stream.Send(&demo.Pong{Stroke: req.Stroke}); err != nil {
			return err
		}
	}
}

func (h *Demo) FindCategoryById(ctx context.Context, req *demo.FindByIdReq, rsp *demo.CategoryRsp) error {
	svc := service.NewCategoryService()
	cate, err := svc.FindCategoryById(1)
	if err != nil {
		return err
	}

	return common.SwapTo(cate, rsp)
}

func (h *Demo) FindAllCategory(ctx context.Context, req *demo.FindAllReq, rsp *demo.CategoryListRsp) error {
	svc := service.NewCategoryService()
	cate, err := svc.FindAllCategory()
	if err != nil {
		return err
	}

	slice2list(cate, rsp)

	return nil
}

func slice2list(from []model.Category, rsp *demo.CategoryListRsp) {
	for _, v := range from {
		r := &demo.CategoryRsp{}
		err := common.SwapTo(v, r)
		if err != nil {
			log.Error()
			break
		}

		rsp.Category = append(rsp.Category, r)
	}
}
